public class L_2_3andL_2_4andL_2_5 {
    /**
     * 随机数函数  Math.random() 返回一个double数,位于[0,1)之间
     */

    /**
     * 返回x=0~1上,x^2的概率
     * 其原理是使用随机数获取0~1上的任意一个数X1,并和另一个0~1上的随机数X2作比较,取其中最大的,其中Math.max()的概率计算为 x * x ,x为取得其中某数区间的概率
     * 例如Math.max()中,设 x  =0.9,那么需要我们两个数都处在0 ~ 0.9上,概率为0.9,Math.max()的结果就是 0.9 * 0.9 = 0.81
     *
     * @return
     */
    static double xToXPower2() {
        return Math.max(Math.random(),Math.random());
    }

    /**
     * 同上,返回x=0~1上,x^3的概率
     * @return
     */
    static double xToXPower3() {
        return Math.max(Math.random(),Math.max(Math.random(),Math.random()));
    }

    /**
     * 返回1-5直接的随机一个数
     * @return
     */
    static int f1() {
        return (int) (Math.random() * 5) + 1;
    }


    /**
     * 调用f1()函数的随机特性
     * 实现返回0,1随机数
     * @return
     */
    static int f2() {
        int ans;
        int flag;
        do {
            ans = f1();
            flag = ans < 3 ? 0 : 1;
        } while (ans==5);
        return flag;
    }

    /**
     * 返回0-7的随机数
     */
    static int f3() {
        int ans;
        do {
            ans = (f2() << 3) + (f2() << 2) + (f2() << 1) + (f2() << 0);
        } while (ans > 7);
        return ans;
    }

    /**
     * 以0.84概率返回0,其他情况返回1
     * @return
     */
    static int f4() {
        return Math.random() > 0.84 ? 1 : 0;
    }

    /**
     * 实现用f4()获得等概率的0和1
     * @return
     */
    static int f5() {
        /*
        int i,j;
        boolean x,y;
        do {
            i = f4();
            j = f4();
            x = i == 0 ? true : false;
            y = j == 0 ? true : false;
        } while (!(x^y));
        */

        int ans = 0;
        do {
            ans = f4();
        } while (ans == f4());
//        return i;
        return ans;
    }




    public static void main(String[] args) {
        double x = 0.6;
        int count = 0;
        int testTimes = 1000000;
        int ans = (int) (Math.random() * 10);
        System.out.println(ans);
        for (int i = 0; i < testTimes; i++) {
            if (xToXPower3() < x) {
                count++;
            }
        }
        System.out.println((double) count/(double) testTimes);
        System.out.println(Math.pow(x, 3));

        count = 0;

        for (int i = 0; i < testTimes; i++) {
            if (f3() < 1) {
                count++;
            }
        }
        System.out.println((double) count/(double) testTimes);

        count = 0;

        for (int i = 0; i < testTimes; i++) {
            if (f5() == 1) {
                count++;
            }
        }
        System.out.println((double) count/(double) testTimes);



        //输出0.12474,0.125317    非常接近0.125

    }
}
